import os
import time
import requests
from datetime import datetime
import math
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.use('TkAgg')  # 或者 'Qt5Agg'
plt.ion()  # 开启交互模式
listJZ = []
list_time = []


def get_gz_history(fund_code):
    for i in range(0, 10):  # 爬取12个月的历史净值
        url = f"http://api.fund.eastmoney.com/f10/lsjz?fundCode={fund_code}&pageIndex={i + 1}&pageSize=20"
        headers = {
            'Referer': 'http://fundf10.eastmoney.com',
            'User-Agent': 'Mozilla/5.0'
        }
        r = requests.get(url, headers=headers, timeout=20)
        data = r.json()['Data']['LSJZList']
        for get_ls_num in range(len(data)):
            listJZ.append(float(data[get_ls_num]['DWJZ']))  # 保存所有历史净值
            list_time.append(data[get_ls_num]['FSRQ'])  # 保存最近更新的历史净值的时间

if __name__ == '__main__':
    jj_rc = pd.read_excel(r'../Fund_form_files/JJ_bd.xlsx', dtype={'基金代码': str, '基金名称': str, '板块': str})
    jj_code = jj_rc['基金代码'].values
    jj_name = jj_rc['基金名称'].values
    jj_type = jj_rc['板块'].values
    for code in range(len(jj_code)):
        near_xh = []
        print(f'正在模拟交易{jj_name[code]}({jj_code[code]})')
        get_gz_history(jj_code[code])
        day = len(listJZ) - 1
        upper_band = 0
        lower_band = 0
        log_dir = '回测表log'
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        with open(f'回测表log/{code+1}{jj_name[code]}({jj_type[code]})', 'w', encoding='utf-8') as f2:
            f2.write(f'{jj_name[code]}({jj_type[code]})\n')
            for j in range(len(listJZ)):
                price = listJZ[day]
                if day < len(listJZ) - 5:
                    ma5 = sum(listJZ[-(len(listJZ) - day - 1):][:5]) / 5
                else:
                    ma5 = 0
                if day < len(listJZ) - 10:
                    ma10 = sum(listJZ[-(len(listJZ) - day - 1):][:10]) / 10
                else:
                    ma10 = 0
                if day < len(listJZ) - 20:
                    ma20 = sum(listJZ[-(len(listJZ) - day - 1):][:20]) / 20
                else:
                    ma20 = 0
                if ma5 != 0 and ma20 != 0 and ma10 != 0:
                    if day < len(listJZ) - 6:  # 确保有足够数据计算前一天的MA
                        today_ma5 = sum(listJZ[-(len(listJZ) - day):][:5]) / 5  # 今天的MA5
                    else:
                        today_ma5 = 0
                    if day < len(listJZ) - 11:  # 确保有足够数据计算前一天的MA
                        today_ma10 = sum(listJZ[-(len(listJZ) - day):][:10]) / 10  # 今天的MA10
                    else:
                        today_ma10 = 0
                    if day < len(listJZ) - 21:  # 确保有足够数据计算前一天的MA20
                        today_ma20 = sum(listJZ[-(len(listJZ) - day):][:20]) / 20  # 今天的MA20
                    else:
                        today_ma20 = 0
                    my_bz_c = math.sqrt(
                        sum((x - ma20) ** 2 for x in listJZ[-(len(listJZ) - day - 1):][:20]) / 20)  # 计算20日标准差(波动率)
                    my_bz_c5 = math.sqrt(
                        sum((x - ma5) ** 2 for x in listJZ[-(len(listJZ) - day - 1):][:5]) / 5)  # 计算5日标准差(波动率)
                    upper_band = ma20 + 2 * my_bz_c  # 布林带上轨
                    lower_band = ma20 - 2 * my_bz_c  # 布林带下轨
                    # 💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦
                    if today_ma5 != 0 and today_ma20 != 0:
                        # 金叉条件：今日ma5>ma20 且 昨日ma5<=ma20
                        if ma5 < ma20 and today_ma5 > today_ma20 and price < upper_band:
                            f2.write(f'💰金叉({list_time[day]})\n')
                            near_xh.append(f'💰金叉({list_time[day]})')
                        # 死叉条件：今日ma5<ma20 且 昨日ma5>=ma20
                        elif ma5 > ma20 and today_ma5 < today_ma20:
                            f2.write(f'💀死叉({list_time[day]})\n')
                            near_xh.append(f'💀死叉({list_time[day]})')
                    # 💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦💦
                # ============================================================
                begin_day = datetime.strptime(list_time[len(listJZ) - 1], "%Y-%m-%d")
                now_day = datetime.strptime(list_time[day], "%Y-%m-%d")
                tz_days = now_day - begin_day
                day = day - 1
            listJZ.clear()
        print(f'最后一次信号{near_xh[-1]}')